<template>
    <div id="hy-swiper">
        <div class="swiper"
             @touchstart="touchStart"
             @touchmove="touchMove"
             @touchend="touchEnd">
            <slot>
            </slot>
        </div>
        <!-- <slot name="indicator">
        </slot> -->
        <div class="indicator">
            <slot name="indicator"
                  v-if="showIndicator && itemCount>1">

                <div v-for="(item, index) in itemCount"
                     class="indi-item"
                     :class="{active: index === currentItemIndex-1}"
                     :key="index"></div>
            </slot>
        </div>
    </div>
</template>

<script>
export default {
    name: "Swiper",
    props: {
        //轮播间隔时间
        intervalTime: {
            type: Number,
            default: 3000
        },
        //轮播动作耗时
        durationTime: {
            type: Number,
            default: 500
        },
        //拖动幅度占比
        moveRatio: {
            type: Number,
            default: .25
        },
        //指示器标记
        showIndicator: {
            type: Boolean,
            default: true
        }
    },
    data: function () {
        return {
            itemCount: 0,
            currentItemIndex: 1,
            swiperStyle: {},
            totalWidth: 0,
            scrolling: false,
        }
    },
    mounted: function () {
        setTimeout(() => {
            //触发DOM初始化
            this.setDOM();
            //触发定时器
            //this.startTimer();
        }, 300)
    },
    methods: {
        handleTransitionEnd: function (e) {
            this.setTransitionTime(0);
            //需要等待上次动画执行结束，才能把transition设置为0
            if (this.currentItemIndex >= this.itemCount + 1) {
                //当到达结尾增加的第一幅轮播图时
                this.currentItemIndex = 1;
                this.setTransform(-this.currentItemIndex * this.totalWidth);
            }
            if (this.currentItemIndex <= 0) {
                //当到达开始增加的最后一幅轮播图时
                this.currentItemIndex = this.itemCount;
                this.setTransform(-this.currentItemIndex * this.totalWidth);
            }
            //设置滚动标识
            this.scrolling = false;

        },
        //DOM设置
        setDOM: function () {
            let swiperEl = document.querySelector('.swiper');
            let swiperItems = swiperEl.getElementsByClassName('slide');
            this.itemCount = swiperItems.length;
            if (this.itemCount > 1) {
                let firstItemClone = swiperItems[0].cloneNode(true);
                let lastItemClone = swiperItems[this.itemCount - 1].cloneNode(true);
                swiperEl.insertBefore(lastItemClone, swiperItems[0]);
                swiperEl.appendChild(firstItemClone);
                this.totalWidth = swiperEl.offsetWidth;
                //提取swiperEl的样式对象，更改swiperStyle即实时更改swiperEl.style
                this.swiperStyle = swiperEl.style;
                //设置动画执行后回调
                swiperEl.addEventListener("transitionend", this.handleTransitionEnd);
                swiperEl.addEventListener("webkitTransitionEnd", this.handleTransitionEnd);
                //初始化轮播图位置
                this.setTransform(-this.totalWidth);
            }
        },
        //设置transform
        setTransform: function (position) {
            this.swiperStyle.transform = `translate3d(${position}px, 0, 0)`;
            this.swiperStyle['-webkit-transform'] = `translate3d(${position}px), 0, 0`;
            this.swiperStyle['-ms-transform'] = `translate3d(${position}px), 0, 0`;
        },

        //设置transitionTime
        setTransitionTime: function (durationTime) {
            this.swiperStyle.transition = 'transform ' + durationTime + 'ms';
        },

        //启动计时
        startTimer: function () {
            this.playTimer = setInterval(() => {
                this.currentItemIndex++;
                this.scrollContent(-this.currentItemIndex * this.totalWidth, this.durationTime);
            }, this.intervalTime)
        },

        //关闭计时
        stopTimer: function () {
            window.clearInterval(this.playTimer);
        },

        //滚动内容页
        scrollContent: function (position, time) {
            //设置滚动标识
            this.scrolling = true;
            //执行滚动
            this.setTransitionTime(time);
            this.setTransform(position);

        },

        touchStart: function (e) {
            this.stopTimer();
            if (this.scrolling) {
                this.moveFlag = false;
                return;//正在滚动时，不可以拖动
            }
            this.moveDistance = 0;
            this.moveStartX = e.touches[0].pageX;
        },

        touchMove (e) {
            if (!this.moveFlag) { return false }
            this.movingX = e.touches[0].pageX;
            this.moveDistance = this.movingX - this.moveStartX;

            if (Math.abs(this.moveDistance) > this.totalWidth) {
                //拖动的幅度大于totalwidth
                //在移动端出现的机率非常低
                this.moveDistance = this.moveDistance / Math.abs(this.moveDistance) * this.totalWidth
            }
            this.movePosition = this.currentItemIndex * this.totalWidth - this.moveDistance;
            this.setTransform(-this.movePosition);
        },

        touchEnd (e) {
            if (!this.moveFlag) {
                this.moveFlag = true
                return false
            }
            let transitionTime = 0;
            if (Math.abs(this.moveDistance) >= (this.moveRatio * this.totalWidth)) {
                //发生页面切换
                if (this.moveDistance > 0) {
                    this.currentItemIndex--;
                } else {
                    this.currentItemIndex++;
                }
                transitionTime = this.durationTime * (this.totalWidth - Math.abs(this.moveDistance)) / this.totalWidth;
            } else {
                transitionTime = this.durationTime * Math.abs(this.moveDistance) / this.totalWidth;
            }
            this.scrollContent(-this.currentItemIndex * this.totalWidth, transitionTime);
            this.startTimer();
        }

    },
}
</script>

<style scoped>
#hy-swiper {
    overflow: hidden;
    position: relative;
}
.swiper {
    display: flex;
}
.indicator {
    display: flex;
    justify-content: center;
    position: absolute;
    width: 100%;
    bottom: 8px;
}
.indi-item {
    box-sizing: border-box;
    width: 8px;
    height: 8px;
    border-radius: 4px;
    background-color: #fff;
    line-height: 8px;
    text-align: center;
    font-size: 12px;
    margin: 0 5px;
}
.indi-item.active {
    background-color: rgba(212, 62, 46, 1);
}
</style>

